package com.tiantian.web.controller.file;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.io.FileUtil;
import com.tiantian.common.annotation.RateLimiter;
import com.tiantian.common.core.controller.BaseController;
import com.tiantian.common.core.domain.ResponseResult;
import com.tiantian.common.enums.LimitType;
import com.tiantian.common.exception.BusinessException;
import com.tiantian.common.utils.StringUtils;
import com.tiantian.common.utils.file.MimeTypeUtils;
import com.tiantian.file.service.JxFileService;
import com.tiantian.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.constraints.NotBlank;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @author TianTian
 */
@RequiredArgsConstructor
@RestController
@RequestMapping("/file")
public class FileController extends BaseController {

    // 默认前缀(桶名称)
    @Value("${jx-minio.baseBucketName}")
    private String BASE_BUCKET_NAME;

    // 图床桶
    @Value("${jx-minio.drawingBedBucketName}")
    private String DRAWING_BED_BUCKET_NAME;

    // minio服务器+图床桶前缀
    @Value("${jx-minio.serverPrefix}")
    private String serverPrefix;

    private final JxFileService jxFileService;
    private final ISysUserService sysUserService;

    /**
     * 上传/更新头像
     *
     * @param avatarFile 文件
     * @return 头像预览地址
     */
    @PostMapping("/uploadAvatar")
    @SaCheckPermission("user")
    @RateLimiter(time = 120, count = 5, limitType = LimitType.IP, message = "更换过于频繁, 请稍后重试")
    public ResponseResult<Map<String, Object>> uploadAvatar(@RequestPart("avatarFile") MultipartFile avatarFile) {
        if (!avatarFile.isEmpty()) {
            String extension = FileUtil.extName(avatarFile.getOriginalFilename());
            // 格式判断
            if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) {
                throw new BusinessException("文件格式不正确，请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式");
            }
            // 上传到minio中
            String avatarURL = jxFileService.uploadObject(avatarFile, "." + extension, BASE_BUCKET_NAME);
            // 将用户头像更新到数据库中
            Long userId = getUserId();
            if (sysUserService.updateUserAvatar(userId, avatarURL) > 0) {
                Map<String, Object> ajax = new HashMap<>();
                ajax.put("imgUrl", avatarURL);
                return ResponseResult.ok(ajax);
            }
        }
        return ResponseResult.fail("上传图片异常,请联系管理员");
    }


    /**
     * 公共图床(每30天自动清理)
     *
     * @return 图片地址
     */
    @PostMapping("/drawingBed")
    @SaCheckPermission({"notice", "setTopic"})
    public ResponseResult<Map<String, Object>> drawingBed(@RequestPart("file") MultipartFile file) {
        if (!file.isEmpty()) {
            String extension = FileUtil.extName(file.getOriginalFilename());
            // 格式判断
            if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) {
                return ResponseResult.fail("文件格式不正确，请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式");
            }
            Map<String, Object> ajax = new HashMap<>();
            String imgUrl = jxFileService.uploadObject(file, extension, DRAWING_BED_BUCKET_NAME);
            ajax.put("imgUrl", imgUrl);
            return ResponseResult.ok(ajax);
        }
        return ResponseResult.fail("图床异常,请联系管理员");
    }

    /**
     * 删除图片
     */
    @DeleteMapping("/removeSourceAvatar")
    @SaCheckPermission({"notice", "setTopic"})
    public ResponseResult<Void> removeSourceAvatar(@RequestParam("avatarURL") @NotBlank(message = "图片地址不能为空") String avatarURL) {
        if (!StringUtils.ishttp(avatarURL)) {
            throw new BusinessException("地址有误");
        }
        boolean b = jxFileService.removeObject(BASE_BUCKET_NAME, avatarURL);
        return toAjax(b);
    }

    /**
     * 删除图片
     *
     * @param url 图片完整地址
     */
    @DeleteMapping("/removePic")
    @SaCheckPermission({"notice", "setTopic"})
    public ResponseResult<Void> removePic(@RequestParam("url") @NotBlank(message = "图片地址不能为空") String url) {
        if (!StringUtils.ishttp(url)) {
            throw new BusinessException("地址有误");
        }
        String dirPath = url.replace(serverPrefix, "");
        boolean b = jxFileService.removeObject(DRAWING_BED_BUCKET_NAME, dirPath);
        return toAjax(b);
    }

    // 邮件:上传附件
    @PostMapping("/uploadFile")
    @SaCheckPermission("mail")
    public ResponseResult<Map<String, Object>> uploadFile(@RequestPart("file") MultipartFile file) {
        if (!file.isEmpty()) {
            String extension = FileUtil.extName(file.getOriginalFilename());
            // 格式判断
            if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION)) {
                return ResponseResult.fail("文件格式不正确，请上传" + Arrays.toString(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION) + "格式");
            }
            Map<String, Object> ajax = new HashMap<>();
            String filePath = jxFileService.uploadObject(file, extension, BASE_BUCKET_NAME);
            ajax.put("filePath", filePath);
            return ResponseResult.ok(ajax);
        }
        return ResponseResult.ok("文件上传失败");
    }
}
